// META: title=test WebNN API element-wise abs operation
// META: global=window,dedicatedworker
// META: variant=?cpu
// META: variant=?gpu
// META: variant=?npu
// META: script=../resources/utils.js
// META: timeout=long

'use strict';

// https://www.w3.org/TR/webnn/#api-mlgraphbuilder-unary
// Compute the absolute value of the input tensor, element-wise.
//
// MLOperand abs(MLOperand input);


const getAbsPrecisionTolerance = (graphResources) => {
  const toleranceValueDict = {float32: 0, float16: 0};
  const expectedDataType =
      getExpectedDataTypeOfSingleOutput(graphResources.expectedOutputs);
  return {metricType: 'ULP', value: toleranceValueDict[expectedDataType]};
};

const absTests = [
  // abs tests
  {
    'name': 'abs float32 positive 0D scalar',
    'graph': {
      'inputs': {
        'absInput': {
          'data': [49.837242126464844],
          'descriptor': {'dimensions': [], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'abs',
        'arguments': [{'input': 'absInput'}],
        'outputs': 'absOutput'
      }],
      'expectedOutputs': {
        'absOutput': {
          'data': [49.837242126464844],
          'descriptor': {'dimensions': [], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'abs float32 negative 0D scalar',
    'graph': {
      'inputs': {
        'absInput': {
          'data': [-91.03521728515625],
          'descriptor': {'dimensions': [], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'abs',
        'arguments': [{'input': 'absInput'}],
        'outputs': 'absOutput'
      }],
      'expectedOutputs': {
        'absOutput': {
          'data': [91.03521728515625],
          'descriptor': {'dimensions': [], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'abs float32 1D constant tensor',
    'graph': {
      'inputs': {
        'absInput': {
          'data': [
            49.837242126464844,  82.09291076660156,  3.1989054679870605,
            85.20904541015625,   88.94609069824219,  -91.03521728515625,
            31.4484920501709,    -29.31110954284668, -92.4477310180664,
            -15.520709991455078, 80.91279602050781,  -38.2097053527832,
            53.064762115478516,  99.6537094116211,   -21.285049438476562,
            90.01982879638672,   18.32451820373535,  -33.06915283203125,
            30.097660064697266,  -74.21503448486328, 95.60974884033203,
            6.614287376403809,   31.2832088470459,   -53.206058502197266
          ],
          'descriptor': {'dimensions': [24], 'dataType': 'float32'},
          'constant': true
        }
      },
      'operators': [{
        'name': 'abs',
        'arguments': [{'input': 'absInput'}],
        'outputs': 'absOutput'
      }],
      'expectedOutputs': {
        'absOutput': {
          'data': [
            49.837242126464844, 82.09291076660156, 3.1989054679870605,
            85.20904541015625,  88.94609069824219, 91.03521728515625,
            31.4484920501709,   29.31110954284668, 92.4477310180664,
            15.520709991455078, 80.91279602050781, 38.2097053527832,
            53.064762115478516, 99.6537094116211,  21.285049438476562,
            90.01982879638672,  18.32451820373535, 33.06915283203125,
            30.097660064697266, 74.21503448486328, 95.60974884033203,
            6.614287376403809,  31.2832088470459,  53.206058502197266
          ],
          'descriptor': {'dimensions': [24], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'abs float32 1D tensor',
    'graph': {
      'inputs': {
        'absInput': {
          'data': [
            49.837242126464844,  82.09291076660156,  3.1989054679870605,
            85.20904541015625,   88.94609069824219,  -91.03521728515625,
            31.4484920501709,    -29.31110954284668, -92.4477310180664,
            -15.520709991455078, 80.91279602050781,  -38.2097053527832,
            53.064762115478516,  99.6537094116211,   -21.285049438476562,
            90.01982879638672,   18.32451820373535,  -33.06915283203125,
            30.097660064697266,  -74.21503448486328, 95.60974884033203,
            6.614287376403809,   31.2832088470459,   -53.206058502197266
          ],
          'descriptor': {'dimensions': [24], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'abs',
        'arguments': [{'input': 'absInput'}],
        'outputs': 'absOutput'
      }],
      'expectedOutputs': {
        'absOutput': {
          'data': [
            49.837242126464844, 82.09291076660156, 3.1989054679870605,
            85.20904541015625,  88.94609069824219, 91.03521728515625,
            31.4484920501709,   29.31110954284668, 92.4477310180664,
            15.520709991455078, 80.91279602050781, 38.2097053527832,
            53.064762115478516, 99.6537094116211,  21.285049438476562,
            90.01982879638672,  18.32451820373535, 33.06915283203125,
            30.097660064697266, 74.21503448486328, 95.60974884033203,
            6.614287376403809,  31.2832088470459,  53.206058502197266
          ],
          'descriptor': {'dimensions': [24], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'abs float32 2D tensor',
    'graph': {
      'inputs': {
        'absInput': {
          'data': [
            49.837242126464844,  82.09291076660156,  3.1989054679870605,
            85.20904541015625,   88.94609069824219,  -91.03521728515625,
            31.4484920501709,    -29.31110954284668, -92.4477310180664,
            -15.520709991455078, 80.91279602050781,  -38.2097053527832,
            53.064762115478516,  99.6537094116211,   -21.285049438476562,
            90.01982879638672,   18.32451820373535,  -33.06915283203125,
            30.097660064697266,  -74.21503448486328, 95.60974884033203,
            6.614287376403809,   31.2832088470459,   -53.206058502197266
          ],
          'descriptor': {'dimensions': [4, 6], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'abs',
        'arguments': [{'input': 'absInput'}],
        'outputs': 'absOutput'
      }],
      'expectedOutputs': {
        'absOutput': {
          'data': [
            49.837242126464844, 82.09291076660156, 3.1989054679870605,
            85.20904541015625,  88.94609069824219, 91.03521728515625,
            31.4484920501709,   29.31110954284668, 92.4477310180664,
            15.520709991455078, 80.91279602050781, 38.2097053527832,
            53.064762115478516, 99.6537094116211,  21.285049438476562,
            90.01982879638672,  18.32451820373535, 33.06915283203125,
            30.097660064697266, 74.21503448486328, 95.60974884033203,
            6.614287376403809,  31.2832088470459,  53.206058502197266
          ],
          'descriptor': {'dimensions': [4, 6], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'abs float32 3D tensor',
    'graph': {
      'inputs': {
        'absInput': {
          'data': [
            49.837242126464844,  82.09291076660156,  3.1989054679870605,
            85.20904541015625,   88.94609069824219,  -91.03521728515625,
            31.4484920501709,    -29.31110954284668, -92.4477310180664,
            -15.520709991455078, 80.91279602050781,  -38.2097053527832,
            53.064762115478516,  99.6537094116211,   -21.285049438476562,
            90.01982879638672,   18.32451820373535,  -33.06915283203125,
            30.097660064697266,  -74.21503448486328, 95.60974884033203,
            6.614287376403809,   31.2832088470459,   -53.206058502197266
          ],
          'descriptor': {'dimensions': [2, 3, 4], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'abs',
        'arguments': [{'input': 'absInput'}],
        'outputs': 'absOutput'
      }],
      'expectedOutputs': {
        'absOutput': {
          'data': [
            49.837242126464844, 82.09291076660156, 3.1989054679870605,
            85.20904541015625,  88.94609069824219, 91.03521728515625,
            31.4484920501709,   29.31110954284668, 92.4477310180664,
            15.520709991455078, 80.91279602050781, 38.2097053527832,
            53.064762115478516, 99.6537094116211,  21.285049438476562,
            90.01982879638672,  18.32451820373535, 33.06915283203125,
            30.097660064697266, 74.21503448486328, 95.60974884033203,
            6.614287376403809,  31.2832088470459,  53.206058502197266
          ],
          'descriptor': {'dimensions': [2, 3, 4], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'abs float32 4D tensor',
    'graph': {
      'inputs': {
        'absInput': {
          'data': [
            49.837242126464844,  82.09291076660156,  3.1989054679870605,
            85.20904541015625,   88.94609069824219,  -91.03521728515625,
            31.4484920501709,    -29.31110954284668, -92.4477310180664,
            -15.520709991455078, 80.91279602050781,  -38.2097053527832,
            53.064762115478516,  99.6537094116211,   -21.285049438476562,
            90.01982879638672,   18.32451820373535,  -33.06915283203125,
            30.097660064697266,  -74.21503448486328, 95.60974884033203,
            6.614287376403809,   31.2832088470459,   -53.206058502197266
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'abs',
        'arguments': [{'input': 'absInput'}],
        'outputs': 'absOutput'
      }],
      'expectedOutputs': {
        'absOutput': {
          'data': [
            49.837242126464844, 82.09291076660156, 3.1989054679870605,
            85.20904541015625,  88.94609069824219, 91.03521728515625,
            31.4484920501709,   29.31110954284668, 92.4477310180664,
            15.520709991455078, 80.91279602050781, 38.2097053527832,
            53.064762115478516, 99.6537094116211,  21.285049438476562,
            90.01982879638672,  18.32451820373535, 33.06915283203125,
            30.097660064697266, 74.21503448486328, 95.60974884033203,
            6.614287376403809,  31.2832088470459,  53.206058502197266
          ],
          'descriptor': {'dimensions': [2, 2, 2, 3], 'dataType': 'float32'}
        }
      }
    }
  },
  {
    'name': 'abs float32 5D tensor',
    'graph': {
      'inputs': {
        'absInput': {
          'data': [
            49.837242126464844,  82.09291076660156,  3.1989054679870605,
            85.20904541015625,   88.94609069824219,  -91.03521728515625,
            31.4484920501709,    -29.31110954284668, -92.4477310180664,
            -15.520709991455078, 80.91279602050781,  -38.2097053527832,
            53.064762115478516,  99.6537094116211,   -21.285049438476562,
            90.01982879638672,   18.32451820373535,  -33.06915283203125,
            30.097660064697266,  -74.21503448486328, 95.60974884033203,
            6.614287376403809,   31.2832088470459,   -53.206058502197266
          ],
          'descriptor': {'dimensions': [2, 1, 4, 1, 3], 'dataType': 'float32'}
        }
      },
      'operators': [{
        'name': 'abs',
        'arguments': [{'input': 'absInput'}],
        'outputs': 'absOutput'
      }],
      'expectedOutputs': {
        'absOutput': {
          'data': [
            49.837242126464844, 82.09291076660156, 3.1989054679870605,
            85.20904541015625,  88.94609069824219, 91.03521728515625,
            31.4484920501709,   29.31110954284668, 92.4477310180664,
            15.520709991455078, 80.91279602050781, 38.2097053527832,
            53.064762115478516, 99.6537094116211,  21.285049438476562,
            90.01982879638672,  18.32451820373535, 33.06915283203125,
            30.097660064697266, 74.21503448486328, 95.60974884033203,
            6.614287376403809,  31.2832088470459,  53.206058502197266
          ],
          'descriptor': {'dimensions': [2, 1, 4, 1, 3], 'dataType': 'float32'}
        }
      }
    }
  }
];

if (navigator.ml) {
  absTests.forEach((test) => {
    webnn_conformance_test(
        buildGraphAndCompute, getAbsPrecisionTolerance, test);
  });
} else {
  test(() => assert_implements(navigator.ml, 'missing navigator.ml'));
}
